/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.model.geo;

import java.awt.geom.CubicCurve2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.QuadCurve2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

/**
 * A class representing a graphics model.
 * For example:
 * <pre>
 *    Model model = new Model();
 *    model.putNode();
 * </pre>
 *
 * @author Fonseca, Flavio & Pitangueira, Roque
 * @since January 2004
 * @see     gui.Interface
 * @see     gui.DrawingArea
 */
public class GeometricModel implements Serializable {
	
	private static final long serialVersionUID = 1L;
	private List<GPoint> marks = new ArrayList<GPoint>();
	private List<GControlPoint> ctrlPoints = new ArrayList<GControlPoint>();
	private List<GPoint> points = new ArrayList<GPoint>();
	private List<Line2D> lines = new ArrayList<Line2D>();
	private List<GQuadCurve> quads = new ArrayList<GQuadCurve>();
	private List<GCubicCurve> cubics = new ArrayList<GCubicCurve>();
	private List<GCurve> curves = new ArrayList<GCurve>();
	private List<GRegion> regions = new ArrayList<GRegion>();
	private int lastLabel = 0;
	
//*****************************************************************************
	
	public void add(GCubicCurve c) {
		cubics.add(c);
		lastLabel++;
		c.setLabel(lastLabel);
	}
	
//*****************************************************************************
	
	/*	public void add(Line2D l) {
		lines.add((GLine)l);
	}
	*/
	
//*****************************************************************************
	
	public void remove(CubicCurve2D c) {
		CubicCurve2D cb;
		
		ListIterator cbs = cubics.listIterator();
		while (cbs.hasNext()) {
			cb = (CubicCurve2D)cbs.next();
			if (cb.equals(c)){
				cbs.remove();
			}
		}
	}
	
//*****************************************************************************
	
	/*	public void removeLine(int index) {
		lines.remove(index);
	}
	
//*****************************************************************************
	
	public Line2D getLine(int index) {
		return (Line2D)lines.get(index);
	}
	*/
	
//*****************************************************************************
	
	public List getCubics() {
		return cubics;
	}
	
//*****************************************************************************
	
	/*	public int indexOf(Line2D l) {
		int index = -1;
		Line2D li;
		ListIterator lns = lines.listIterator();
		while (lns.hasNext()) {
			li = (Line2D)lns.next();
			if (li.equals(l)){
				index = lines.indexOf(li);
			}
		}
		return index;
	}
	
//*****************************************************************************
	
	public void clearLines() {
		lines.clear();
	}
	*/
	
//*****************************************************************************
	
	public void add(GQuadCurve q) {
		quads.add(q);
		lastLabel = lastLabel + 1;
		q.setLabel(lastLabel);
	}
	
//*****************************************************************************
	
	/*	public void add(Line2D l) {
		lines.add((GLine)l);
	}
	*/
	
//*****************************************************************************
	
	public void remove(QuadCurve2D q) {
		QuadCurve2D qu;
		
		ListIterator qds = quads.listIterator();
		while (qds.hasNext()) {
			qu = (QuadCurve2D)qds.next();
			if (qu.equals(q)){
				qds.remove();
			}
		}
	}
	
//*****************************************************************************
	
	/*
	public void removeLine(int index) {
		lines.remove(index);
	}
	
//*****************************************************************************
	
	public Line2D getLine(int index) {
		return (Line2D)lines.get(index);
	}
	*/
	
//*****************************************************************************
	
	public List getQuads() {
		return quads;
	}
	
//*****************************************************************************
	
	/*	public int indexOf(Line2D l) {
		int index = -1;
		Line2D li;
		ListIterator lns = lines.listIterator();
		while (lns.hasNext()) {
			li = (Line2D)lns.next();
			if (li.equals(l)){
				index = lines.indexOf(li);
			}
		}
		return index;
	}
	
//*****************************************************************************
	
	public void clearLines() {
		lines.clear();
	}
	*/
	
//*****************************************************************************
	
	public void add(GLine l) {
		lines.add(l);
		lastLabel = lastLabel + 1;
		l.setLabel(lastLabel);
	}
	
//*****************************************************************************
	
	public void add(Line2D l) {
		lines.add((GLine)l);
	}
	
//*****************************************************************************
	
	public void remove(Line2D l) {
		Line2D li;
		
		ListIterator lns = lines.listIterator();
		while (lns.hasNext()) {
			li = (Line2D)lns.next();
			if (li.equals(l)){
				lns.remove();
			}
		}
	}
	
//*****************************************************************************
	
	public void removeLine(int index) {
		lines.remove(index);
	}
	
//*****************************************************************************
	
	public Line2D getLine(int index) {
		return (Line2D)lines.get(index);
	}
	
//*****************************************************************************
	
	public List getLines() {
		return lines;
	}
	
//*****************************************************************************
	
	public int indexOf(Line2D l) {
		int index = -1;
		Line2D li;
		ListIterator lns = lines.listIterator();
		while (lns.hasNext()) {
			li = (Line2D)lns.next();
			if (li.equals(l)){
				index = lines.indexOf(li);
			}
		}
		return index;
	}
	
//*****************************************************************************
	
	public void clearLines() {
		lines.clear();
	}
	
//*****************************************************************************
    
	public void addMark(GPoint p) {
		marks.add(p);
		lastLabel = lastLabel + 1;
		p.setLabel(lastLabel);
	}
    
//*****************************************************************************
	
	public void add(GPoint p) {
		points.add(p);
		lastLabel = lastLabel + 1;
		p.setLabel(lastLabel);
	}
    
//*****************************************************************************
	
    public void add(Point2D p) {
        GPoint po = new GPoint(p.getX(), p.getY());
        points.add(po);
    }
    
//*****************************************************************************
	
    public void remove(Point2D p) {
        
		//Removing equal points
        ListIterator pts = points.listIterator();
        while (pts.hasNext()) {
            Point2D po = (Point2D)pts.next();
            if (po.equals(p)){
                pts.remove();
            }
        }
        
        //Removing lines connected to that point
        Line2D li;
        ListIterator lns = lines.listIterator();
        while (lns.hasNext()) {
            li = (Line2D)lns.next();
            if ((li.getP1().equals(p)) || (li.getP2().equals(p))) {
                lns.remove();
            }
        }
		
		//Removing equal control points
        pts = ctrlPoints.listIterator();
        while (pts.hasNext()) {
            Point2D po = (Point2D)pts.next();
            if (po.equals(p)){
                pts.remove();
            }
        }
		
    }
    
//*****************************************************************************
	/*public void remove(GControlPoint p) {
		
		//Removing equal control points
        ListIterator pts = ctrlPoints.listIterator();
        while (pts.hasNext()) {
            GControlPoint po = (GControlPoint)pts.next();
            if (po.equals(p)){
                pts.remove();
            }
        }
		
		//Removing lines connected to that point
        Line2D li;
        ListIterator lns = lines.listIterator();
        while (lns.hasNext()) {
            li = (Line2D)lns.next();
            if ((li.getP1().equals(p)) || (li.getP2().equals(p))) {
                lns.remove();
            }
        }
		
	}*/
//*****************************************************************************		
		
    public void removePoint(int index) {
        
        Point2D p = (Point2D)points.get(index);
        
        //Removing lines connected to that point
        Line2D li;
        ListIterator lns = lines.listIterator();
        while (lns.hasNext()) {
            li = (Line2D)lns.next();
            if ((li.getP1().equals(p)) || (li.getP2().equals(p))) {
                lns.remove();
            }
        }
        points.remove(index);
    }
    
//*****************************************************************************
	
    public Point2D getPoint(int index) {
        return (Point2D)points.get(index);
    }
    
//*****************************************************************************
	
    public List getPoints() {
        return points;
    }
    
//*****************************************************************************
	
    public int indexOf(Point2D p) {
        return points.indexOf(p);
    }
    
//*****************************************************************************
	
    public void clearPoints() {
        points.clear();
    }
	
//*****************************************************************************
	
	public void add(GControlPoint p) {
		ctrlPoints.add(p);
		lastLabel = lastLabel + 1;
		p.setLabel(lastLabel);
	}
	
//*****************************************************************************
		
	public void addControl(Point2D p) {
        GControlPoint po = new GControlPoint(p.getX(), p.getY());
        ctrlPoints.add(po);
    }
	
//*****************************************************************************
	
    public void removeControlPoint(int index) {
        
        Point2D p = (Point2D)ctrlPoints.get(index);
        
        //Removing lines connected to that control point
        Line2D li;
        ListIterator lns = lines.listIterator();
        while (lns.hasNext()) {
            li = (Line2D)lns.next();
            if ((li.getP1().equals(p)) || (li.getP2().equals(p))) {
                lns.remove();
            }
        }
		ctrlPoints.remove(index);
    }
    
//*****************************************************************************
	
    public Point2D getControlPoint(int index) {
        return (Point2D)ctrlPoints.get(index);
    }
    
//*****************************************************************************
	
    public List getControlPoints() {
        return ctrlPoints;
    }
    
//*****************************************************************************
	
    public int indexOfControl(Point2D p) {
        return ctrlPoints.indexOf(p);
    }
    
//*****************************************************************************
	
    public void clearControlPoints() {
        ctrlPoints.clear();
    }
	
//*****************************************************************************
	
	public void add(GCurve gc) {
		curves.add(gc);
	}
	
//*****************************************************************************
	
	public List getCurves() {
		return curves;
	}
	
//*****************************************************************************
	
    public void clearCurves() {
        curves.clear();
    }
	
//*****************************************************************************
	
	public void add(GRegion gr) {
		regions.add(gr);
	}
	
//*****************************************************************************
	
	public List getRegions() {
		return regions;
	}
	
//*****************************************************************************
	
    public void clearRegions() {
        regions.clear();
    }
	
//*****************************************************************************
	
	public void setLastLabel(int lb) {
        lastLabel = lb;
    }
	
//*****************************************************************************
	
    public int getLastLabel( ) {
        return lastLabel;
    }
	
//*****************************************************************************
	
	public void clear() {
		points.clear();
		lines.clear();
		quads.clear();
	} 
	
//*****************************************************************************
	
	public void initPartition() {
		ListIterator cbs = cubics.listIterator();
		while(cbs.hasNext()) {
			GCubicCurve gc = (GCubicCurve)cbs.next();
			gc.setNParts(1);
		}
		ListIterator qds = quads.listIterator();
		while(qds.hasNext()) {
			GQuadCurve gq = (GQuadCurve)qds.next();
			gq.setNParts(1);
		}
		ListIterator lns = lines.listIterator();
		while(lns.hasNext()) {
			GLine gl = (GLine)lns.next();
			gl.setNParts(1);
		}
		ListIterator pts = points.listIterator();
		while(pts.hasNext()) {
			GPoint gp = (GPoint)pts.next();
			gp.setNParts(1);
		}
	}
	
//*****************************************************************************
}
